/*
 * app_CAN.c
 *
 *  Created on: 2017��12��12��
 *      Author: think
 */
#include "includes.h"

//-------------public global variable define-----------------------------
const uint8_t TRDP_GRP_IP[TRDP_SEND_IP_CNT+TRDP_RECV_IP_CNT][4] = {{239, 255, 0, 6},
																	{239, 255, 0, 12}};
//----------------private function declare------------------

uint8_t	trdp_comn_data[100];
uint8_t trdp_spec_data[100];
uint8_t trdp_down_data[64];
// check trdp receive state: 0: not receive trdp, 1: received trdp 																	
uint8_t trdp_recv_state = 0;
uint32_t dev_pos_state = 0x10;
//---------------private function define-------------------
static void initTaskWork(void);
static void check_dev_pos(uint32_t pos);
TRDP_MINI_ERR_T trdp_mini_pd_callback(void *arg, INT32U comId, INT8U *pData, INT32U dataSize, INT8U *recvIP, INT16U recvPort, TRDP_MINI_ERR_T errCode);

TRDP_MINI_ERR_T trdp_mini_pd_callback(void *arg, INT32U comId, INT8U *pData, INT32U dataSize, INT8U *recvIP, INT16U recvPort, TRDP_MINI_ERR_T errCode)
{
	TRDP_MINI_ERR_T ret = TRDP_MINI_NO_ERR;

	if(errCode >= 0){
		//errCode == 0, trdp communication is OK, else user should check the errCode to get the err information
		switch(comId){
		case TRDP_RECV_COMID_0:
		case (TRDP_RECV_COMID_0 + 50):
			if(dataSize <= sizeof(trdp_down_data)){
				memcpy(trdp_down_data, pData, sizeof(trdp_down_data));
				trdp_recv_state = 1;
			}
			break;
		default:
			break;
		}
	}

	return ret;
}

static void initTaskWork(void)
{
	// 初始化全局数据缓冲区
	memset(trdp_comn_data, 0, sizeof(trdp_comn_data));
	memset(trdp_spec_data, 0, sizeof(trdp_spec_data));
	memset(trdp_down_data, 0, sizeof(trdp_down_data));
	// 预留时间等待协议栈其他任务准备完成
	vTaskDelay(100);
	// 设置X5口为主ETH接口
	p_gSysUserRegs->curEthMode = WKS_MainTRDP;
	
	//trdp_mini_pd_subscribe(TRDP_RECV_COMID_0,(INT8U *)&TRDP_GRP_IP[TRDP_SEND_IP_CNT][0],(INT8U *)&TRDP_GRP_IP[TRDP_SEND_IP_CNT][0], COM_UDP_MULTICAST, trdp_mini_pd_callback);
	trdp_mini_pd_prepare(TRDP_SEND_COMID_0, trdp_comn_data, sizeof(trdp_comn_data), (INT8U *)p_gSysUserRegs->MR_Para.IP_ADDR, (INT8U *)&TRDP_GRP_IP[0][0], 0, 100, COM_UDP_MULTICAST);
	trdp_mini_pd_prepare(TRDP_SEND_COMID_1, trdp_spec_data, sizeof(trdp_spec_data), (INT8U *)p_gSysUserRegs->MR_Para.IP_ADDR, (INT8U *)&TRDP_GRP_IP[0][0], 0, 100, COM_UDP_MULTICAST);
	// 初始化CAN接口
	BSP_CAN1_Config(CAN1_COM_BANDRATE);								//initial CAN1
	BSP_CAN2_Config(CAN2_COM_BANDRATE);								//initial CAN2
}

static void check_dev_pos(uint32_t pos)
{
	uint32_t storeData[2];
	if( (pos == 1) || (pos == 2) ){
		pos = pos -1 + 0x10;
		if(dev_pos_state != pos){
			BSP_readFlash(FLASH_USER_START_ADDR, (uint8_t *)&storeData[0], 4);
			storeData[1] = pos;
			if(BSP_initWriteFlashSectors() == OK){
				if(BSP_writeFlash(FLASH_USER_START_ADDR,  (uint8_t *)&storeData[0], 8) == OK){
					BSP_lockFlashSectors();
					BSP_SoftReset();
				}
			}
		}
	}
}

void receive_Can1_Frame(uint32_t id, uint8_t *pData, uint32_t len)
{
	switch(id){
		
	case 0xA01: memcpy(&trdp_comn_data[0], pData, 8); break;
	case 0xA02: memcpy(&trdp_comn_data[8], pData, 8); break;
	case 0xA03: memcpy(&trdp_comn_data[16], pData, 8); break;
	case 0xA04: memcpy(&trdp_comn_data[24], pData, 8); break;
	case 0xA05: memcpy(&trdp_comn_data[32], pData, 8); break;
	case 0xA06: memcpy(&trdp_comn_data[40], pData, 8); break;
	case 0xA07: memcpy(&trdp_comn_data[48], pData, 8); break;
	case 0xA08: memcpy(&trdp_comn_data[56], pData, 8); break;
	case 0xA09: memcpy(&trdp_comn_data[64], pData, 8); break;
	case 0xA0A: memcpy(&trdp_comn_data[72], pData, 8); break;

	case 0xB01: memcpy(&trdp_spec_data[0], pData, 8); break;
	case 0xB02: memcpy(&trdp_spec_data[8], pData, 8); break;
	case 0xB03: memcpy(&trdp_spec_data[16], pData, 8); break;
	case 0xB04: memcpy(&trdp_spec_data[24], pData, 8); break;
	case 0xB05: memcpy(&trdp_spec_data[32], pData, 8); break;
	case 0xB06: memcpy(&trdp_spec_data[40], pData, 8); break;
	case 0xB07: memcpy(&trdp_spec_data[48], pData, 8); break;
	case 0xB08: memcpy(&trdp_spec_data[56], pData, 8); break;
	case 0xB09: memcpy(&trdp_spec_data[64], pData, 8); break;
	case 0xB0A: memcpy(&trdp_spec_data[72], pData, 8); break;

	// pass other can frame
	default: break;
	}
}

void receive_Can2_Frame(uint32_t id, uint8_t *pData, uint32_t len)
{
	receive_Can1_Frame(id, pData, len);
}


void TASK_PROC( void *pvParameters )
{
	uint32_t	tickCnt=0;
	TickType_t xLastWakeTime;
	const TickType_t xFrequency = 10;
	
	
	initTaskWork();
	// Initialise the xLastWakeTime variable with the current time.
	xLastWakeTime = xTaskGetTickCount ();

	while(1){
		// Wait for the next cycle(5ms).
		vTaskDelayUntil( &xLastWakeTime, xFrequency );
		tickCnt++;

		trdp_mini_pd_update(TRDP_SEND_COMID_0, trdp_comn_data, sizeof(trdp_comn_data));
		trdp_mini_pd_update(TRDP_SEND_COMID_1, trdp_spec_data, sizeof(trdp_spec_data));

#if 0
		if(((tickCnt % 20) == 0) && (trdp_recv_state == 1)){
			BSP_Can1WriteData(1, 0xA01, &trdp_down_data[0], 8);
			BSP_Can2WriteData(1, 0xA01, &trdp_down_data[0], 8);
			vTaskDelay(10);

			BSP_Can1WriteData(1, 0xA02, &trdp_down_data[8], 8);
			BSP_Can2WriteData(1, 0xA02, &trdp_down_data[8], 8);
			vTaskDelay(10);

			BSP_Can1WriteData(1, 0xA03, &trdp_down_data[16], 8);
			BSP_Can2WriteData(1, 0xA03, &trdp_down_data[16], 8);
			vTaskDelay(10);

			BSP_Can1WriteData(1, 0xA04, &trdp_down_data[24], 8);
			BSP_Can2WriteData(1, 0xA04, &trdp_down_data[24], 8);
			vTaskDelay(10);

			BSP_Can1WriteData(1, 0xA05, &trdp_down_data[32], 8);
			BSP_Can2WriteData(1, 0xA05, &trdp_down_data[32], 8);
			vTaskDelay(10);

			BSP_Can1WriteData(1, 0xA06, &trdp_down_data[40], 8);
			BSP_Can2WriteData(1, 0xA06, &trdp_down_data[40], 8);
			vTaskDelay(10);

			BSP_Can1WriteData(1, 0xA07, &trdp_down_data[48], 8);
			BSP_Can2WriteData(1, 0xA07, &trdp_down_data[48], 8);
		}
#endif
	}
}

